﻿<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8" />
    <style>
        a, b, body, div, font, h1, h2, h3, h4, i, input, lp, select, td, u {
            font-family: Arial,宋体;
            font-size: 16px;
        }

            a:link {
                text-decoration: none;
            }

        table {
            border: 0;
            border-collapse: collapse;
            border-spacing: 0;
            width: 100%;
        }

        label {
            display: inline-block;
            width: 150px;
        }

        pre {
            white-space: pre-wrap;
            word-wrap: break-word;
        }

        .trClass {
            height: 40px;
            vertical-align: bottom;
        }

        .trMethod {
            height: 30px;
        }

        .tdMethod {
            width: 20%;
        }

        .trLeft {
            height: 20px;
        }

        .tdParam {
            border-right: 1px solid #C3C3C3;
            border-bottom: 1px solid #C3C3C3;
            padding-left: 5px;
        }

        .aTitle {
            font-size: 20px;
            margin-left: 20px;
        }

        .logTitle {
            background: green;
            padding: 4px 4px 4px 4px;
        }

        .divCaption {
            background: #F1F1F1;
            border: 1px solid #E0E0E0;
            padding: 10px 0px 10px 0px;
        }

        .divContent {
            display: flex;
            justify-content: center;
            flex-direction: column;
            align-items: center;
        }
    </style>
</head>
<body style="margin: 0; padding: 0; height: 100%;">
    <div style="position: fixed; left: 50%; top: 50%; width: 800px; height: 800px; margin-left: -400px; margin-top: -400px; ">
        <div class="divCaption">
            <span class="aTitle">数据库初始化向导</span>
        </div>
        <div style="border: 1px solid #E0E0E0; padding: 20px; height: 300px; margin-top: -1px">
            <div id="divFirst" class="divContent">
                <div>
                    <label>数据库类型</label>
                    <select id="dbtype" onchange="onDbChanged(this.value)" style="width:203px;padding:1px 2px">
                        <option value="0">PostgreSql</option>
                        <option value="1">MySql</option>
                        <option value="2">Oracle</option>
                        <option value="3">Sql Server</option>
                    </select><br /><br />
                    <label>主机</label>
                    <input type="text" id="host" value="10.10.1.2"><br /><br />
                    <label>端口</label>
                    <input type="text" id="port" value="5432"><br /><br />
                    <label id="lbldefdb">默认库名</label>
                    <input id="defdb" type="text" value="postgres"><br /><br />
                    <label>用户名 </label>
                    <input type="text" id="defuser" value="postgres"><br /><br />
                    <label>密码</label>
                    <input id="pwd" type="password"><br /><br />
                    <input id="btnConnec" type="button" value="连　　接" style="width:100%;" onclick="onConnect()">
                    <label style="color: red; width: auto; margin-top: 10px;">* 确保该用户具有增删库权限</label>
                </div>
            </div>
            <div id="divSecond" class="divContent" style="display: none">
                <div>
                    <label id="lbldb">库名</label>
                    <input type="text" id="newdb"><br /><br />
                    <label>用户名</label>
                    <input type="text" id="newuser"><br /><br />
                    <label>密码</label>
                    <input id="newpwd" type="password"><br /><br />
                    <input id="btn0" type="button" value="导　　入　　库" style="width: 100%;" onclick="onDoInit(0)">
                    <input id="btn1" type="button" value="创　建　新　库" style="width: 100%; margin-top: 10px;" onclick="onDoInit(1)">
                    <input id="btn2" type="button" value="返　回" style="width: 100%; margin-top: 10px;" onclick="onBack()">
                    <div style="margin-top: 20px;">
                        <label style="color: red; width: auto;">说明</label><br />
                        <label style="color: red; width: auto;">1. 导入库时将删除旧的同名表、视图等</label><br />
                        <label style="color: red; width: auto;">2. 创建新库时若库或用户已存在将删除重建</label><br />
                    </div>
                </div>
                
            </div>
        </div>
        <div class="divCaption" style="margin-top:10px">
            <span class="aTitle">输出日志</span>
        </div>
        <div style="padding: 10px 10px 10px 10px; background: black; color: white; overflow: auto; height: 340px;">
            <pre id="log"></pre>
        </div>
     </div>

    <script>
        var _rpcUrl = location.href.substr(0, location.href.lastIndexOf("/")) + "/.c";
        window.onload = function ()
        {
            receiveLog();
        }

        function onDbChanged(db)
        {
            if (db == 1)
            {
                $("port").value = "3306";
                $("defuser").value = "root";
                $("lbldefdb").innerText = "无需填写";
                $("defdb").setAttribute("readonly", "readonly");
                $("defdb").value = "";
                $("lbldb").innerText = "新库名";
            }
            else if (db == 2)
            {
                $("port").value = "1521";
                $("defuser").value = "system";
                $("defdb").style = "visibility:visible";
                $("lbldefdb").innerText = "服务名";
                $("defdb").removeAttribute("readOnly");
                $("defdb").value = "orcl";
                $("lbldb").innerText = "新表空间";
            }
            else if (db == 3)
            {
                $("port").value = "1433";
                $("defuser").value = "sa";
                $("defdb").style = "visibility:visible";
                $("lbldefdb").innerText = "默认库名";
                $("defdb").removeAttribute("readOnly");
                $("defdb").value = "master";
                $("lbldb").innerText = "新库名";
            }
            else if (db == 0)
            {
                $("port").value = "5432";
                $("defuser").value = "postgres";
                $("defdb").style = "visibility:visible";
                $("lbldefdb").innerText = "默认库名";
                $("defdb").removeAttribute("readOnly");
                $("defdb").value = "postgres";
                $("lbldb").innerText = "新库名";
            }
        }

        async function onConnect()
        {
            if (!isConnectValid())
                return;

            $("btnConnec").disabled = "disabled";
            var list = "[\"&ss\",\""
                + $("dbtype").value + "\",\""
                + $("host").value + "\",\""
                + $("port").value + "\",\""
                + $("defdb").value + "\",\""
                + $("defuser").value + "\",\""
                + $("pwd").value + "\"]";
                
            var msg = await call("[\"TestConnect\"," + list + "]");
            if (msg != null && msg != "")
            {
                alert(msg);
            }
            else
            {
                $("divFirst").style = "display: none";
                $("divSecond").style = "display: flex";
            }
            $("btnConnec").disabled = "";
        }

        async function onDoInit(isNewDb)
        {
            if (!isValid())
                return;

            var info;
            if (isNewDb == 0)
            {
                info = "导入库时将删除旧的同名表、视图等！！！\r\n是否继续？";
            }
            else
            {
                info = "创建新库时若库或用户已存在将删除重建！！！\r\n是否继续？";
            }
            if (confirm(info) == false)
                return;

            toggleButton(true);
            var list = "[\"&ss\",\""
                + $("dbtype").value + "\",\""
                + $("host").value + "\",\""
                + $("port").value + "\",\""
                + $("defdb").value + "\",\""
                + $("defuser").value + "\",\""
                + $("pwd").value + "\",\""
                + $("newdb").value + "\",\""
                + $("newuser").value + "\",\""
                + $("newpwd").value + "\"]";

            var msg = await call("[\"IsExists\"," + list + "," + isNewDb + "]");
            if (msg != null && msg != "")
            {
                if (isNewDb == 0)
                {
                    // 导入
                    alert(msg);
                    toggleButton(false);
                    return;
                }
                else
                {
                    // 新库
                    if (confirm(msg + "\r\n3") == false
                        || confirm(msg + "\r\n2") == false
                        || confirm(msg + "\r\n1") == false)
                    {
                        toggleButton(false);
                        return;
                    }
                }
            }

            await call("[\"DoInit\"," + list + "," + isNewDb + "]");
            toggleButton(false);
        }

        function onBack()
        {
            $("divFirst").style = "display: flex";
            $("divSecond").style = "display: none";
        }

        function toggleButton(p_disabled)
        {
            if (p_disabled)
            {
                $("btn0").disabled = "disabled";
                $("btn1").disabled = "disabled";
                $("btn2").disabled = "disabled";
            }
            else
            {
                $("btn0").disabled = "";
                $("btn1").disabled = "";
                $("btn2").disabled = "";
            }
        }

        function isConnectValid()
        {
            var suc = false;
            if ($("host").value == "")
            {
                $("host").focus();
            }
            else if ($("port").value == "")
            {
                $("port").focus();
            }
            else if ($("defdb").value == "" && $("dbtype").value != 1)
            {
                $("defdb").focus();
            }
            else if ($("defuser").value == "")
            {
                $("defuser").focus();
            }
            else if ($("pwd").value == "")
            {
                $("pwd").focus();
            }
            else
            {
                suc = true;
            }
            return suc;
        }

        function isValid()
        {
            var suc = false;
            if ($("host").value == "")
            {
                $("host").focus();
            }
            else if ($("port").value == "")
            {
                $("port").focus();
            }
            else if ($("defdb").value == "" && $("dbtype").value != 1)
            {
                $("defdb").focus();
            }
            else if ($("defuser").value == "")
            {
                $("defuser").focus();
            }
            else if ($("pwd").value == "")
            {
                $("pwd").focus();
            }
            else if ($("newdb").value == "")
            {
                $("newdb").focus();
            }
            else if ($("newuser").value == "")
            {
                $("newuser").focus();
            }
            else if ($("newpwd").value == "")
            {
                $("newpwd").focus();
            }
            else
            {
                suc = true;
            }
            return suc;
        }

        function $(id)
        {
            return document.getElementById(id);
        }

        function call(content)
        {
            return new Promise(function (resolve, reject)
            {
                var xhr = new XMLHttpRequest();
                xhr.responseType = "arraybuffer";
                xhr.open("post", _rpcUrl, true);
                xhr.onload = function ()
                {
                    if (xhr.status != 200)
                        return;

                    var result = JSON.parse(readFrame(xhr.response));
                    if (result.length != 2)
                    {
                        alert("调用失败！");
                    }
                    else if (result[0] == 1)
                    {
                        alert(result[1]);
                        toggleButton(false);
                    }
                    else
                    {
                        resolve(result[1]);
                    }
                };
                xhr.send(writeFrame(content));
            });
        }

        function writeFrame(str)
        {
            // Frame内容
            var data = [];
            var len, c;
            len = str.length;
            for (var i = 0; i < len; i++)
            {
                c = str.charCodeAt(i);
                if (c >= 0x010000 && c <= 0x10FFFF)
                {
                    data.push(((c >> 18) & 0x07) | 0xF0);
                    data.push(((c >> 12) & 0x3F) | 0x80);
                    data.push(((c >> 6) & 0x3F) | 0x80);
                    data.push((c & 0x3F) | 0x80);
                }
                else if (c >= 0x000800 && c <= 0x00FFFF)
                {
                    data.push(((c >> 12) & 0x0F) | 0xE0);
                    data.push(((c >> 6) & 0x3F) | 0x80);
                    data.push((c & 0x3F) | 0x80);
                }
                else if (c >= 0x000080 && c <= 0x0007FF)
                {
                    data.push(((c >> 6) & 0x1F) | 0xC0);
                    data.push((c & 0x3F) | 0x80);
                }
                else
                {
                    data.push(c & 0xFF);
                }
            }

            // Frame头
            var header = [];
            // 始终不压缩
            header.push(0 & 0xFF);
            // 内容长度
            len = data.length;
            header.push((len >> 24) & 0xFF);
            header.push((len >> 16) & 0xFF);
            header.push((len >> 8) & 0xFF);
            header.push(len & 0xFF);

            return new Uint8Array(header.concat(data));
        }

        function readFrame(buf)
        {
            // 1字节压缩标志 + 4字节内容长度
            var arr = new Uint8Array(buf);

            // Frame内容，始终不压缩
            var data = arr.slice(5);

            // 字节转utf8
            var str = "";
            for (var i = 0; i < data.length; i++)
            {
                var one = data[i].toString(2),
                    v = one.match(/^1+?(?=0)/);
                if (v && one.length == 8)
                {
                    var bytesLength = v[0].length;
                    var store = data[i].toString(2).slice(7 - bytesLength);
                    for (var st = 1; st < bytesLength; st++)
                    {
                        store += data[st + i].toString(2).slice(2);
                    }
                    str += String.fromCharCode(parseInt(store, 2));
                    i += bytesLength - 1;
                }
                else
                {
                    str += String.fromCharCode(data[i]);
                }
            }
            return str;
        }

        /************************ 日志 ************************/
        var logRequest = null;
        var logIndex = 0;
        var _logUrl = location.href.substr(0, location.href.lastIndexOf("/")) + "/.log?index=";

        function receiveLog()
        {
            if (logRequest !== null)
            {
                logRequest.abort();
                logRequest = null;
            }

            logRequest = new XMLHttpRequest();
            logRequest.open("get", _logUrl + logIndex, true);
            logRequest.onload = function ()
            {
                if (logRequest.status == 200)
                {
                    // 返回格式：日志索引+日志列表
                    var split = logRequest.response.indexOf("+");
                    if (split > -1)
                    {
                        logIndex = logRequest.response.substring(0, split);
                        $("log").innerHTML += logRequest.response.substring(split + 1);
                    }

                    // 再次请求
                    receiveLog();
                }
            };
            logRequest.send();
        }
    </script>
</body>
</html>